#include <iostream>
#include <string>
#include "httplib.h"
#include "add_contact.pb.h"

using namespace std;
using namespace httplib;

class ContactException{
    private:
        std::string message;
    public:
        ContactException(std::string str = "A problem") : message(str){}
        std::string what() const {
            return message;
        }
};

void printContacts(add_contact::AddContactRequest& request) {
    cout << "联系人姓名：" << request.name() << endl;
    cout << "联系人年龄：" << request.age() << endl;
    for (int i = 0; i < request.phone_size(); i++) {
        const add_contact::AddContactRequest_Phone& phone = request.phone(i);
        cout << "联系人电话" << i + 1 << ": " << phone.number();
        cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
    }
}

static unsigned int random_char() {
    // 用于随机数引擎获得随机种子
    std::random_device rd;
    // mt19937是c++11新特性，它是一种随机数算法，用法与rand()函数类似，但是mt19937具有速度快，周期长的特点
    // 作用是生成伪随机数
    std::mt19937 gen(rd());
    // 随机生成一个整数 i 范围[0, 255]
    std::uniform_int_distribution<> dis(0, 255);
    return dis(gen);
}

// 生成UUID（通用唯一标识符）
static string generate_hex(const unsigned int len) {
    std::stringstream ss;
    // 生成len个16进制随机数，将其拼接而成
    for (auto i = 0; i < len; i++) {
        const auto rc = random_char();
        std::stringstream hexstream;
        hexstream << std::hex << rc;
        auto hex = hexstream.str();
        ss << (hex.length() < 2 ? '0' + hex : hex);
    }
    return ss.str();
}


int main()
{
    cout << "----------------服务启动-----------------" << endl;
    Server server;
    server.Post("/contacts/add", [](const Request& req, Response& res){
        cout << "接收到post请求！" << endl;
        
        add_contact::AddContactRequest request;
        add_contact::AddContactResponse response;
        try {
            // 1. 反序列化 request: req.body
            if (!request.ParseFromString(req.body)) {
                throw ContactException("AddContactRequest 反序列失败！");
            }
            // 2. 新增联系人，打印新增联系人信息
            printContacts(request);

            // 3. 构造response: res.body
            response.set_success(true);
            response.set_uid(generate_hex(10));

            // 4. 序列化 response
            string response_str;
            if (!response.SerializeToString(&response_str)) {
                throw ContactException("AddContactResponse 序列化失败！");
            }
            // 5. 设置res
            res.status = 200;
            res.body = response_str;
            res.set_header("Content-Type", "application/protobuf");
        } catch (const ContactException& e) {
            res.status = 50;
            response.set_success(false);
            response.set_error_desc(e.what());
            string response_str;
            if (response.SerializeToString(&response_str)) {
                res.body = response_str;
                res.set_header("Content-Type", "application/protobuf");
            }
            cout << "/contacts/add 发生异常，异常信息：" << e.what() << endl;
        }
    });

    server.listen("0.0.0.0", 8080);
    return 0;
}

// 测试httplib用
// int main()
// {
//     cout << "----------------服务启动-----------------" << endl;
//     Server server;
//     server.Post("/test-post", [](const Request& req, Response& res){
//         cout << "接收到post请求！" << endl;
//         res.status = 200;
//     });

//     server.Get("/test-get", [](const Request& req, Response& res){
//         cout << "接收到get请求！" << endl;
//         res.status = 200;
//     });

//     server.listen("0.0.0.0", 8080);
//     return 0;
// }